#ifndef NET_EVENT_LOOP_H
#define NET_EVENT_LOOP_H

#include "poller.h"
#include "channel.h"
#include "timer_wheel.h"
#include <thread>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <memory>
#include <functional>
#include <cassert>

namespace net {

/**
 * @class EventLoop
 * @brief 事件循环核心类，管理Channel和Poller，处理I/O事件和任务调度
 * @details 每个EventLoop对应一个线程，负责监控事件、处理就绪事件和执行任务队列
 */
class EventLoop {
public:
    using Functor = std::function<void()>;

    /**
     * @brief 构造函数，创建EventLoop实例
     * @details 初始化线程ID、创建Poller和事件fd，设置为非阻塞模式
     *          并创建事件fd用于唤醒事件循环
     */
    EventLoop();

    /**
     * @brief 析构函数，关闭事件fd和Poller
     * @details 确保在析构时清理资源，避免内存泄漏
     *          并记录日志信息
     */
    ~EventLoop();

    // 禁止拷贝和移动
    EventLoop(const EventLoop&) = delete;
    EventLoop& operator=(const EventLoop&) = delete;
    EventLoop(EventLoop&&) = delete;
    EventLoop& operator=(EventLoop&&) = delete;

    /**
     * @brief 启动事件循环
     * @details 循环执行：监控事件->处理就绪事件->执行任务队列
     */
    void start();

    /**
     * @brief 判断当前线程是否为EventLoop所属线程
     * @return 是返回true，否则返回false
     */
    bool isInLoop() const
    { return (_threadId == std::this_thread::get_id()); }

    /**
     * @brief 断言当前线程是EventLoop所属线程，否则触发调试断言
     */
    void assertInLoop() const
    { assert(isInLoop()); }

    /**
     * @brief 在EventLoop所属线程执行任务
     * @param cb 待执行的任务回调
     * @details 若当前线程是EventLoop线程则直接执行，否则加入任务队列
     */
    void runInLoop(const Functor& cb);

    /**
     * @brief 将任务加入队列，唤醒EventLoop线程执行
     * @param cb 待执行的任务回调
     */
    void queueInLoop(const Functor& cb);

    /**
     * @brief 更新Channel的事件监控状态
     * @param channel 待更新的Channel
     */
    void updateEvent(Channel* channel);

    /**
     * @brief 移除Channel的事件监控
     * @param channel 待移除的Channel
     */
    void removeEvent(Channel* channel);

    /**
     * @brief 退出事件循环
     */
    void quit();

    // 定时器相关接口
    void timerAdd(uint64_t id, uint32_t delay, const TaskFunc& cb)
    { return _timerWheel.timerAdd(id, delay, cb); }

    void timerRefresh(uint64_t id)
    { return _timerWheel.timerRefresh(id); }

    void timerCancel(uint64_t id)
    { return _timerWheel.timerCancel(id); }

    bool hasTimer(uint64_t id)
    { return _timerWheel.hasTimer(id); }

    std::thread::id threadId() const
    { return _threadId; }    

private:
    /**
     * @brief 执行任务队列中所有任务
     * @details 批量取出任务并执行，减少锁竞争
     */
    void runAllTask();

    /**
     * @brief 创建eventfd用于唤醒事件循环
     * @return 成功返回eventfd，失败触发致命错误
     */
    static int createEventFd();

    /**
     * @brief 读取eventfd数据（用于清除唤醒信号）
     */
    void readEventfd();

    /**
     * @brief 写入数据到eventfd（用于唤醒事件循环）
     */
    void wakeUpEventFd();

    std::atomic<bool> _quit;                    // 退出标志
    std::thread::id _threadId;                  // EventLoop所属线程ID
    std::unique_ptr<Poller> _poller;            // 事件多路分发器
    int _eventFd;                               // 用于唤醒事件循环的eventfd
    std::unique_ptr<Channel> _eventChannel;     // 管理eventfd的Channel
    std::vector<Functor> _tasks;                // 任务队列
    mutable std::mutex _mutex;                  // 保护任务队列的互斥锁
    TimerWheel _timerWheel;                     // 定时器轮
};

/**
 * @class LoopThread
 * @brief 管理单个EventLoop线程的类
 * @details 每个LoopThread对应一个线程和一个EventLoop实例
 */
class LoopThread {
public:
    LoopThread();
    ~LoopThread();

    // 禁止拷贝和移动
    LoopThread(const LoopThread&) = delete;
    LoopThread& operator=(const LoopThread&) = delete;
    LoopThread(LoopThread&&) = delete;
    LoopThread& operator=(LoopThread&&) = delete;

    /**
     * @brief 获取当前线程的EventLoop实例
     * @return 指向EventLoop的指针（确保已初始化）
     */
    EventLoop* getLoop();

private:
    /**
     * @brief 线程入口函数
     * @details 在新线程中创建EventLoop并启动事件循环
     */
    void threadEntry();

    std::mutex _mutex;              // 保护_eventLoop的互斥锁
    std::condition_variable _cond;  // 用于等待EventLoop初始化完成
    EventLoop* _eventLoop;          // 线程内的EventLoop实例
    std::thread _thread;            // 线程对象
};

/**
 * @class LoopThreadPool
 * @brief EventLoop线程池类
 * @details 管理多个LoopThread，实现EventLoop的轮询分配
 */
class LoopThreadPool {
public:
    /**
     * @brief 构造函数
     * @param base_loop 主线程的EventLoop（当线程数为0时使用）
     */
    explicit LoopThreadPool(EventLoop* base_loop);
    ~LoopThreadPool();

    // 禁止拷贝和移动
    LoopThreadPool(const LoopThreadPool&) = delete;
    LoopThreadPool& operator=(const LoopThreadPool&) = delete;
    LoopThreadPool(LoopThreadPool&&) = delete;
    LoopThreadPool& operator=(LoopThreadPool&&) = delete;

    /**
     * @brief 设置线程池大小
     * @param count 线程数量
     */
    void setThreadCount(int count)
    { _threadCount = count; }

    /**
     * @brief 创建线程池中的所有线程
     */
    void create();

    /**
     * @brief 轮询获取下一个EventLoop
     * @return 指向EventLoop的指针
     */
    EventLoop* nextLoop();

    /**
     * @brief 停止所有EventLoop
     */
    void stop();

private:
    int _threadCount;                   // 线程池大小
    int _nextIdx;                       // 下一个分配的EventLoop索引（轮询用）
    EventLoop* _baseLoop;               // 主线程EventLoop
    std::vector<std::unique_ptr<LoopThread>> _threads;  // 线程列表
    std::vector<EventLoop*> _loops;     // EventLoop列表
};

} // namespace net

#endif // NET_EVENT_LOOP_H